feat: add lock / unlock functionality to agg_bridge for native miden assets#2771
feat: add lock / unlock functionality to agg_bridge for native miden assets#2771partylikeits1983 wants to merge 9 commits intoagglayerfrom
agg_bridge for native miden assets#2771Conversation
…and metadata hash
…h for native tokens
agg_bridge for native miden assets
Bumps rand 0.9.2 → 0.9.4 and rand 0.10.0 → 0.10.1 to resolve RUSTSEC-2026-0097 flagged by `cargo deny check` in CI.
650b79d to
d1d9938
Compare
Fumuran
left a comment
There was a problem hiding this comment.
Looks good, thank you!
It is a partial review, for now I only reviewed masm code. Mostly formatting suggestions and code optimizations
| #! 1. KEY [0, 0, fid_s, fid_p] -> [addr0, addr1, addr2, addr3] (origin address part 1) | ||
| #! 2. KEY [1, 0, fid_s, fid_p] -> [addr4, origin_network, scale, 0] (origin address part 2) |
There was a problem hiding this comment.
nit: I'm not sure about fid abbreviation, it could be not immediately clear. I would vote for faucet_id_suffux and faucet_id_prefix
| # Offset in the local memory of the `hash_token_address` procedure | ||
| const TOKEN_ADDR_HASH_PTR = 0 | ||
|
|
||
| # Local memory offsets for `register_faucet` |
There was a problem hiding this comment.
nit: it could be not clear whether the register_faucet is a procedure, storage slot or something else
| # Local memory offsets for `register_faucet` | |
| # Offsets in the local memory of the `register_faucet` procedure |
| const REG_TOKEN_HASH_LOC = 0 | ||
| const REG_FID_S_LOC = 4 | ||
| const REG_FID_P_LOC = 5 | ||
| const REG_SCALE_LOC = 6 | ||
| const REG_ORIGIN_NETWORK_LOC = 7 | ||
| const REG_IS_NATIVE_LOC = 8 |
There was a problem hiding this comment.
optional nit: I would use more detailed names, though it is indeed not obvious how to express these pointers clearly but briefly
| movup.7 movup.7 movup.7 movup.7 | ||
| # => [addr0, addr1, addr2, addr3, 0, 0, fid_s, fid_p, addr4, pad(11)] | ||
|
|
||
| swapw | ||
| # => [0, 0, fid_s, fid_p, addr0, addr1, addr2, addr3, addr4, pad(11)] |
There was a problem hiding this comment.
I believe that these lines could be removed
| push.FAUCET_METADATA_MAP_SLOT[0..2] | ||
| exec.native_account::set_map_item | ||
| dropw | ||
| # => [addr4, pad(11)] |
There was a problem hiding this comment.
nit:
# => [addr4, pad(15)]
| # Drop the remaining pad to start fresh | ||
| dropw dropw dropw | ||
| # => [] |
There was a problem hiding this comment.
I'm not sure that this will work, since we are in the note script
| # Pad to 16 (need 6 more zeros) | ||
| padw push.0.0 | ||
| # => [0, 0, 0, 0, 0, 0, addr0, addr1, addr2, addr3, addr4, fid_s, fid_p, scale, origin_network, is_native] | ||
|
|
||
| # Load remaining origin_token_addr_[0..3] onto the stack | ||
| padw mem_loadw_le.ORIGIN_TOKEN_ADDR_0 | ||
| # => [addr0, addr1, addr2, addr3, addr4, faucet_id_suffix, faucet_id_prefix, pad(13)] | ||
| # Move 6 pad zeros to the end | ||
| movdn.15 movdn.15 movdn.15 movdn.15 movdn.15 movdn.15 | ||
| # => [addr0, addr1, addr2, addr3, addr4, fid_s, fid_p, scale, origin_network, is_native, pad(6)] |
There was a problem hiding this comment.
I'm not sure that this is needed
| # Drop all 16 pad elements and rebuild the stack | ||
| dropw dropw dropw dropw | ||
| # => [] |
| # Pad to 16 (need 6 more) | ||
| padw push.0.0 | ||
| # => [0, 0, 0, 0, 0, 0, fid_s, fid_p, MH_LO, MH_HI] |
| call.bridge_config::store_faucet_metadata_hash | ||
| # => [pad(16)] | ||
|
|
||
| dropw dropw dropw dropw |
There was a problem hiding this comment.
I suppose this works only because we were explicitly padding to the 16 elements before call, but once everything else is updated, we should be able to remove this line
Closes #2700. Adds a lock/unlock path for Miden-native tokens to the AggLayer bridge, mirroring
PolygonZkEVMBridgeV2.claimAsset()'s handling oforiginNetwork == networkID.The bridge no longer needs to be the faucet's owner to support it, so user-created faucets are now bridgeable once the bridge admin registers them via a
CONFIG_AGG_BRIDGEnote withis_native = true. Registration is still admin-gated (register_faucetis caller-restricted); what changed is the ownership requirement.Approach
Native faucet branch, end-to-end:
is_native, calllock_asset→native_account::add_assetto park the asset in the bridge's own vault. NoBURNnote is emitted.is_native, callunlock_and_send→native_account::remove_asset+p2id::newto emit aP2IDnote to the recipient. NoMINTnote, no faucet ntx.PROOF_DATA_KEYis used as the serial number so the note commitment is deterministic per claim.Metadata moved to the bridge. All three FPI calls from the bridge into the faucet (
asset_to_origin_asset,get_metadata_hash,get_scale) are replaced with bridge-local reads out of a newfaucet_metadata_map.A single map with four faucet-ID-keyed sub-keys holds everything:
[0, 0, fid_s, fid_p][addr0, addr1, addr2, addr3][1, 0, fid_s, fid_p][addr4, origin_network, scale, 0][2, 0, fid_s, fid_p][mh_lo0..3][3, 0, fid_s, fid_p][mh_hi0..3]faucet_registry_mapis extended from[1, 0, 0, 0]to[1, is_native, 0, 0], which is backward-compatible since existing entries haveis_native = 0implicitly.CONFIG_AGG_BRIDGEcarries the full metadata payload at registration (split across two calls to fit the 16-element stack).AggLayer faucet slimmed. With metadata on the bridge, the faucet's conversion-info / metadata-hash slots and its
asset_to_origin_asset/get_metadata_hash/get_scaleprocs are dead code. Removed: theAggLayerFaucetcomponent now only re-exportsmint_and_send+burnon top ofOwnable2Step+OwnerControlled. A Miden-native faucet which wants to integrate with Agglayer, now is just a plain network fungible faucet, no AggLayer-specific storage or FPI surface needed.Follow-ups
Not in this PR; filing separately per @bobbinth's comments in the original issue for this PR:
faucet_registry_mapintofaucet_metadata_mapby parkingis_nativein sub-key 1's 4th limb. Needs a new presence check (origin-address-word non-zero) before landing.nameon-chain (AggLayer: store token name in faucet storage #2585).